﻿using System;
using UnityEngine;
using Unity.Mathematics;

namespace Jinndev {

    public struct Int2 : IEquatable<Int2> {

        public static readonly Int2 zero = new Int2(0);
        public static readonly Int2 one = new Int2(1);

        public int x;
        public int y;

        public Int2(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public Int2(int value) {
            x = value;
            y = value;
        }

        public Int2(int[] array) {
            x = array.Length >= 1 ? array[0] : 0;
            y = array.Length >= 2 ? array[1] : 0;
        }

        public int[] ToArray() {
            return new int[] { x, y };
        }


        public static implicit operator Int2(int2 v) {
            return new Int2(v.x, v.y);
        }

        public static implicit operator int2(Int2 v) {
            return new int2(v.x, v.y);
        }

        public static bool operator ==(Int2 lhs, Int2 rhs) {
            return lhs.Equals(rhs);
        }

        public static bool operator !=(Int2 lhs, Int2 rhs) {
            return !lhs.Equals(rhs);
        }

        #region Int2 Int2
        public static Int2 operator +(Int2 a, Int2 b) {
            return new Int2(a.x + b.x, a.y + b.y);
        }
        public static Int2 operator -(Int2 a, Int2 b) {
            return new Int2(a.x - b.x, a.y - b.y);
        }
        public static Int2 operator *(Int2 a, Int2 b) {
            return new Int2(a.x * b.x, a.y * b.y);
        }
        public static Int2 operator /(Int2 a, Int2 b) {
            return new Int2(a.x / b.x, a.y / b.y);
        }
        #endregion


        #region Int2 float
        public static Float2 operator +(Int2 a, float b) {
            return new Float2(a.x + b, a.y + b);
        }
        public static Float2 operator +(float a, Int2 b) {
            return new Float2(a + b.x, a + b.y);
        }
        public static Float2 operator -(Int2 a, float b) {
            return new Float2(a.x - b, a.y - b);
        }
        public static Float2 operator -(float a, Int2 b) {
            return new Float2(a - b.x, a - b.y);
        }
        public static Float2 operator *(Int2 a, float b) {
            return new Float2(a.x * b, a.y * b);
        }
        public static Float2 operator *(float a, Int2 b) {
            return new Float2(a * b.x, a * b.y);
        }
        public static Float2 operator /(Int2 a, float b) {
            return new Float2(a.x / b, a.y / b);
        }
        public static Float2 operator /(float a, Int2 b) {
            return new Float2(a / b.x, a / b.y);
        }
        #endregion

        #region Int2 % int
        public static Int2 operator %(Int2 a, int b) {
            return new Int2(a.x % b, a.y % b);
        }
        public static Int2 operator %(int a, Int2 b) {
            return new Int2(a % b.x, a % b.y);
        }
        #endregion

        #region Int2 Vector2
        public static Vector2 operator +(Int2 a, Vector2 b) {
            return new Vector2(a.x + b.x, a.y + b.y);
        }
        public static Vector2 operator +(Vector2 a, Int2 b) {
            return new Vector2(a.x + b.x, a.y + b.y);
        }
        public static Vector2 operator -(Int2 a, Vector2 b) {
            return new Vector2(a.x - b.x, a.y - b.y);
        }
        public static Vector2 operator -(Vector2 a, Int2 b) {
            return new Vector2(a.x - b.x, a.y - b.y);
        }
        public static Vector2 operator *(Int2 a, Vector2 b) {
            return new Vector2(a.x * b.x, a.y * b.y);
        }
        public static Vector2 operator *(Vector2 a, Int2 b) {
            return new Vector2(a.x * b.x, a.y * b.y);
        }
        public static Vector2 operator /(Int2 a, Vector2 b) {
            return new Vector2(a.x / b.x, a.y / b.y);
        }
        public static Vector2 operator /(Vector2 a, Int2 b) {
            return new Vector2(a.x / b.x, a.y / b.y);
        }
        #endregion

        #region Int2 float2
        public static float2 operator +(Int2 a, float2 b) {
            return new float2(a.x + b.x, a.y + b.y);
        }
        public static float2 operator +(float2 a, Int2 b) {
            return new float2(a.x + b.x, a.y + b.y);
        }
        public static float2 operator -(Int2 a, float2 b) {
            return new float2(a.x - b.x, a.y - b.y);
        }
        public static float2 operator -(float2 a, Int2 b) {
            return new float2(a.x - b.x, a.y - b.y);
        }
        public static float2 operator *(Int2 a, float2 b) {
            return new float2(a.x * b.x, a.y * b.y);
        }
        public static float2 operator *(float2 a, Int2 b) {
            return new float2(a.x * b.x, a.y * b.y);
        }
        public static float2 operator /(Int2 a, float2 b) {
            return new float2(a.x / b.x, a.y / b.y);
        }
        public static float2 operator /(float2 a, Int2 b) {
            return new float2(a.x / b.x, a.y / b.y);
        }
        #endregion

        #region Int2 int
        public static Int2 operator +(Int2 a, int b) {
            return new Int2(a.x + b, a.y + b);
        }
        public static Int2 operator +(int a, Int2 b) {
            return new Int2(a + b.x, a + b.y);
        }
        public static Int2 operator -(Int2 a, int b) {
            return new Int2(a.x - b, a.y - b);
        }
        public static Int2 operator -(int a, Int2 b) {
            return new Int2(a - b.x, a - b.y);
        }
        public static Int2 operator *(Int2 a, int b) {
            return new Int2(a.x * b, a.y * b);
        }
        public static Int2 operator *(int a, Int2 b) {
            return new Int2(a * b.x, a * b.y);
        }
        public static Int2 operator /(Int2 a, int b) {
            return new Int2(a.x / b, a.y / b);
        }
        public static Int2 operator /(int a, Int2 b) {
            return new Int2(a / b.x, a / b.y);
        }
        #endregion

        #region Int2 int2
        public static Int2 operator +(Int2 a, int2 b) {
            return new Int2(a.x + b.x, a.y + b.y);
        }
        public static int2 operator +(int2 a, Int2 b) {
            return new int2(a.x + b.x, a.y + b.y);
        }
        public static Int2 operator -(Int2 a, int2 b) {
            return new Int2(a.x - b.x, a.y - b.y);
        }
        public static int2 operator -(int2 a, Int2 b) {
            return new int2(a.x - b.x, a.y - b.y);
        }
        public static Int2 operator *(Int2 a, int2 b) {
            return new Int2(a.x * b.x, a.y * b.y);
        }
        public static int2 operator *(int2 a, Int2 b) {
            return new int2(a.x * b.x, a.y * b.y);
        }
        public static Int2 operator /(Int2 a, int2 b) {
            return new Int2(a.x / b.x, a.y / b.y);
        }
        public static int2 operator /(int2 a, Int2 b) {
            return new int2(a.x / b.x, a.y / b.y);
        }
        #endregion

        public bool Equals(Int2 other) {
            return other.x == x && other.y == y;
        }

        public override bool Equals(object obj) {
            return obj is Int2 && Equals((Int2)obj);
        }

        public override int GetHashCode() {
            return (int)math.hash(new int2(x, y));
        }

        public override string ToString() {
            return $"Int2({x}, {y})";
        }

    }

}
